Relatório Formal com Tidyplots

Author
Affiliation

Gabriel Rodrigues, MSc

Published

October 30, 2025

Abstract

Relatório formal de análise de dados feito utilizando a plataforma Quarto® com linguagem R. O relatório possui uma breve introdução dos dados juntamente com seu processamento e o delineamento de hipóteses. Testes estatísticos foram realizados para validar as hipóteses e o pacote Tidyplots foi utilizado para a construção de gráficos.

Keywords

Data Science, Testes estatísticos, Tidyplots

Introdução

Esse relatório é complementar à Atividade Prática 06, realizada dia 28 de Outubro em sala de aula. O relatório possui o intuito de representar como um relatório de dados formal deve ser estruturado, juntamento com as operações de processamento de dados e códigos no R.

Resumo dos dados

Os dados utilizados aqui serão vindos da tabela world-data-2023.csv, que representa um compilado abrangente de indicadores globais por país, referente ao ano de 2023.

As principais categorias de dados incluem:

  • Demografia e Geografia: Informações sobre População, Densidade (P/Km2), Área Terrestre (Km2), População Urbana, Taxa de Natalidade, Taxa de Fertilidade e Expectativa de Vida.

  • Economia e Finanças: Dados vitais como Produto Interno Bruto (PIB), Índice de Preços ao Consumidor (IPC e sua variação), Código da Moeda, Salário Mínimo, Receita Tributária (%), Taxa de Imposto Total, e o Preço da Gasolina.

  • Saúde e Educação: Indicadores sociais cruciais, incluindo Mortalidade Infantil e Materna, proporção de Médicos por Mil, Despesas de Saúde do bolso próprio, e as taxas de matrícula bruta nos ensinos primário e superior.

  • Meio Ambiente e Recursos: Métricas ambientais como as Emissões de CO2​ e a porcentagem de Terra Agrícola e Área Florestal.

  • Força de Trabalho e Segurança: Informações sobre a participação da Força de Trabalho, Taxa de Desemprego e o Tamanho das Forças Armadas.

Em resumo, é um dataset de múltiplas facetas destinado a fornecer um perfil detalhado e estatístico de cada país.

Importando os dados

Para importar esse dataset, utilizaremos a função read.csv() para importar um conjunto de dados diretamente da web. Atenção: Esse tipo de importação só é possível se os dados estiverem de forma integral no link.

df <- read.csv("https://raw.githubusercontent.com/gabrielvpina/dataScience/refs/heads/main/data/world-data-2023.csv")

Utilizando a função skim do pacote skimr nos dados:

# importar pacote
library(skimr)
# chamar função de resumo
skim(df)
Data summary
Name df
Number of rows 195
Number of columns 35
_______________________
Column type frequency:
character 26
numeric 9
________________________
Group variables None

Variable type: character

skim_variable n_missing complete_rate min max empty n_unique whitespace
Country 0 1 4 32 0 195 0
Density..P.Km2. 0 1 1 6 0 137 0
Abbreviation 0 1 0 2 7 189 0
Agricultural.Land…. 0 1 0 6 7 169 0
Land.Area.Km2. 0 1 0 10 1 195 0
Armed.Forces.size 0 1 0 9 24 106 0
Capital.Major.City 0 1 0 22 3 193 0
Co2.Emissions 0 1 0 9 7 185 0
CPI 0 1 0 8 17 176 0
CPI.Change…. 0 1 0 7 16 87 0
Currency.Code 0 1 0 3 15 134 0
Forested.Area…. 0 1 0 6 7 162 0
Gasoline.Price 0 1 0 6 20 102 0
GDP 0 1 0 20 2 194 0
Gross.primary.education.enrollment…. 0 1 0 7 7 142 0
Gross.tertiary.education.enrollment…. 0 1 0 7 12 172 0
Largest.city 0 1 0 23 6 189 0
Minimum.wage 0 1 0 7 45 115 0
Official.language 0 1 0 22 1 78 0
Out.of.pocket.health.expenditure 0 1 0 6 7 161 0
Population 0 1 0 13 1 195 0
Population..Labor.force.participation…. 0 1 0 6 19 146 0
Tax.revenue…. 0 1 0 6 26 120 0
Total.tax.rate 0 1 0 7 12 157 0
Unemployment.rate 0 1 0 6 19 165 0
Urban_population 0 1 0 11 5 191 0

Variable type: numeric

skim_variable n_missing complete_rate mean sd p0 p25 p50 p75 p100 hist
Birth.Rate 6 0.97 20.21 9.95 5.90 11.30 17.95 28.75 46.08 ▇▆▃▃▁
Calling.Code 1 0.99 360.55 323.24 1.00 82.50 255.50 506.75 1876.00 ▇▂▂▁▁
Fertility.Rate 7 0.96 2.70 1.28 0.98 1.71 2.24 3.60 6.91 ▇▅▃▂▁
Infant.mortality 6 0.97 21.33 19.55 1.40 6.00 14.00 32.70 84.50 ▇▂▂▁▁
Life.expectancy 8 0.96 72.28 7.48 52.80 67.00 73.20 77.50 85.40 ▂▃▅▇▅
Maternal.mortality.ratio 14 0.93 160.39 233.50 2.00 13.00 53.00 186.00 1150.00 ▇▁▁▁▁
Physicians.per.thousand 7 0.96 1.84 1.68 0.01 0.33 1.46 2.94 8.42 ▇▅▂▁▁
Latitude 1 0.99 19.09 23.96 -40.90 4.54 17.27 40.12 64.96 ▂▃▇▆▅
Longitude 1 0.99 20.23 66.72 -175.20 -7.94 20.97 48.28 178.07 ▁▃▇▃▂

Primeiras impressões

Com o resumo dos dados em mãos, pode-se observar que diversas colunas que deveriam ser numéricas estão sendo lidas como strings. As principais causas são:

  • Uso de vírgula para representar decimais, enquanto o R utiliza pontos
  • Caracteres associados à porcentagens (ex: 23.12%)
  • Caracteres associados à valores monetários (“$”)

Outra coisa para se atentar são os nomes das colunas, que antes continham espaços e símbolos na tabela original e agora tiveram modificações automáticas devido à função de importação do R.

# nomes vindos da importação
colnames(df)
 [1] "Country"                                  
 [2] "Density..P.Km2."                          
 [3] "Abbreviation"                             
 [4] "Agricultural.Land...."                    
 [5] "Land.Area.Km2."                           
 [6] "Armed.Forces.size"                        
 [7] "Birth.Rate"                               
 [8] "Calling.Code"                             
 [9] "Capital.Major.City"                       
[10] "Co2.Emissions"                            
[11] "CPI"                                      
[12] "CPI.Change...."                           
[13] "Currency.Code"                            
[14] "Fertility.Rate"                           
[15] "Forested.Area...."                        
[16] "Gasoline.Price"                           
[17] "GDP"                                      
[18] "Gross.primary.education.enrollment...."   
[19] "Gross.tertiary.education.enrollment...."  
[20] "Infant.mortality"                         
[21] "Largest.city"                             
[22] "Life.expectancy"                          
[23] "Maternal.mortality.ratio"                 
[24] "Minimum.wage"                             
[25] "Official.language"                        
[26] "Out.of.pocket.health.expenditure"         
[27] "Physicians.per.thousand"                  
[28] "Population"                               
[29] "Population..Labor.force.participation...."
[30] "Tax.revenue...."                          
[31] "Total.tax.rate"                           
[32] "Unemployment.rate"                        
[33] "Urban_population"                         
[34] "Latitude"                                 
[35] "Longitude"                                

Vamos checar agora o total de valores vazios NAs no dataset:

# a função table() conta categorias do vetor gerado pela função is.na()
table(is.na(df))

FALSE  TRUE 
 6774    51 

São 51 itens vazios em um total de 6774 itens totais da tabela, isso representa aproximadamente 0.75% dos valores totais no nosso dataset.

Processamento dos dados

Inicialmente vamos corrigir os nomes das colunas e as colunas com porcentagens que estão sendo lidas como string devido ao caractere “%”.

Nomes das Colunas

A função colnames() retorna o nome das colunas de um dataset, ela também pode ser utilizada para enviar um novo conjunto de nomes para as colunas de um dataset.

# vamos usar a função colnames(df) para ver as colunas originais e ir inserindo os novos nomes no vertor "novos_nomes"
novos_nomes <- c(
    "Pais",
    "Densidade", # 'Density (P/Km2)'
    "Abreviacao",
    "TerraAgriculturaPercentual", # 'Agricultural Land( %)'
    "AreaTerrestreKm2", # 'Land Area(Km2)'
    "TamanhoForcasArmadas", # 'Armed Forces size'
    "TaxaNatalidade", # 'Birth Rate'
    "CodigoDiscagem", # 'Calling Code'
    "CapitalCidadePrincipal", # 'Capital/Major City'
    "EmissoesCO2", # 'Co2-Emissions'
    "IPC", # 'CPI'
    "MudancaIPCPercentual", # 'CPI Change (%)'
    "CodigoMoeda", # 'Currency-Code'
    "TaxaFertilidade", # 'Fertility Rate'
    "AreaFlorestadaPercentual", # 'Forested Area (%)'
    "PrecoGasolina", # 'Gasoline Price'
    "PIB", # 'GDP'
    "MatriculaPrimariaBrutaPercentual", # 'Gross primary education enrollment (%)'
    "MatriculaSuperiorBrutaPercentual", # 'Gross tertiary education enrollment (%)'
    "MortalidadeInfantil", # 'Infant mortality'
    "MaiorCidade", # 'Largest city'
    "ExpectativaVida", # 'Life expectancy'
    "TaxaMortalidadeMaterna", # 'Maternal mortality ratio'
    "SalarioMinimo", # 'Minimum wage'
    "LinguaOficial", # 'Official language'
    "GastoSaudeProprioBolso", # 'Out of pocket health expenditure'
    "MedicosPorMil", # 'Physicians per thousand'
    "Populacao",
    "PopulacaoForcaTrabalhoPercentual", # 'Population: Labor force participation (%)'
    "ReceitaFiscalPercentual", # 'Tax revenue (%)'
    "TaxaImpostoTotal", # 'Total tax rate'
    "TaxaDesemprego", # 'Unemployment rate'
    "PopulacaoUrbana", # 'Urban_population'
    "Latitude",
    "Longitude"
)

# Usando a função colnames() para inserir os novos nomes de coluna
colnames(df) <- novos_nomes

# Mostrar novos nomes
colnames(df)
 [1] "Pais"                             "Densidade"                       
 [3] "Abreviacao"                       "TerraAgriculturaPercentual"      
 [5] "AreaTerrestreKm2"                 "TamanhoForcasArmadas"            
 [7] "TaxaNatalidade"                   "CodigoDiscagem"                  
 [9] "CapitalCidadePrincipal"           "EmissoesCO2"                     
[11] "IPC"                              "MudancaIPCPercentual"            
[13] "CodigoMoeda"                      "TaxaFertilidade"                 
[15] "AreaFlorestadaPercentual"         "PrecoGasolina"                   
[17] "PIB"                              "MatriculaPrimariaBrutaPercentual"
[19] "MatriculaSuperiorBrutaPercentual" "MortalidadeInfantil"             
[21] "MaiorCidade"                      "ExpectativaVida"                 
[23] "TaxaMortalidadeMaterna"           "SalarioMinimo"                   
[25] "LinguaOficial"                    "GastoSaudeProprioBolso"          
[27] "MedicosPorMil"                    "Populacao"                       
[29] "PopulacaoForcaTrabalhoPercentual" "ReceitaFiscalPercentual"         
[31] "TaxaImpostoTotal"                 "TaxaDesemprego"                  
[33] "PopulacaoUrbana"                  "Latitude"                        
[35] "Longitude"                       

Corrigir colunas lidas como string

Colunas com porcentagem (%)

Para corrigir as colunas que possuem um caractere % em seus itens, utiliza-se uma substituição por um item vazio (““). Para isso emprega-se a função gsub() para substituir "%" -> "". Normalmente a função gsub() funciona individualmente para cada coluna, por isso deve-se utilizar a função lapply() associada a ela, de forma que gsub() funcione em um loop para as colunas selecionadas.

# colunas com caractere de porcentagem (%)
colunas_erradas <- c("TaxaDesemprego", "TaxaImpostoTotal", "ReceitaFiscalPercentual", "PopulacaoForcaTrabalhoPercentual", "GastoSaudeProprioBolso", "MatriculaSuperiorBrutaPercentual", "MatriculaPrimariaBrutaPercentual", "AreaFlorestadaPercentual", "MudancaIPCPercentual", "TerraAgriculturaPercentual")

# aplicando gsub nas colunas escolhidas
df[colunas_erradas] <- lapply(df[colunas_erradas], gsub, pattern = "%", replacement = "") # trocar porcentagem por vazio

# transformando as colunas em numericas
df[colunas_erradas] <- lapply(df[colunas_erradas], as.numeric)

Colunas com cifrão ($)

Com isso resolvemos as colunas com %, agora vamos aplicar a mesma lógica para colunas com cifrão $. Entretanto 0 cifrão é um metacaractere em expressões regulares que geralmente indica o fim da string. Para tratar o $ como um caractere literal que você deseja remover, ele precisa ser “escapado” com barras invertidas duplas \\$.

colunas_cifrao <- c("SalarioMinimo", "PrecoGasolina")

df[colunas_cifrao] <- lapply(df[colunas_cifrao], gsub, pattern = "\\$", replacement = "")

df[colunas_cifrao] <- lapply(df[colunas_cifrao], as.numeric)

Colunas com vírgula

A partir da substituição do cifrão nas colunas, é possível realizar a substituição das vírgulas nas colunas e convertê-las para colunas numéricas. Podemos checar com head(df) os nossos dados e selecionar as colunas erradas.

É necessário fazer uma diferença, pois em colunas como PopulacaoUrbana, Populacao, PIB e EmissoesCO2 existe um padrão diferente de notação, onde as vírgulas estão somente para diferenciar visualmente os milhates das centenas e das dezenas, e não uma representação decimal.

colunas_cifrao <- c("PIB")

df[colunas_cifrao] <- lapply(df[colunas_cifrao], gsub, pattern = "\\$", replacement = "")

colunas_virg <- c("PopulacaoUrbana", "Populacao", "PIB", "EmissoesCO2", "AreaTerrestreKm2", "Densidade", "TamanhoForcasArmadas")

df[colunas_virg] <- lapply(df[colunas_virg], gsub, pattern = ",", replacement = "")

df[colunas_virg] <- lapply(df[colunas_virg], as.numeric)

Agora todas as colunas estão formatadas para as análises estatísticas e gráficos.

Análises Univariadas

A partir dos dados já convertidos podemos realizar análises de distribuição dos dados.

Densidade dos dados

# importar pacotes
library(tidyverse)
library(ggplot2)
library(tidyr)
library(dplyr)

colunas_para_plotar <- c(
    "TaxaNatalidade",
    "TaxaFertilidade",
    "ExpectativaVida",
    "TaxaDesemprego",
    "TerraAgriculturaPercentual",
    "AreaTerrestreKm2",
    "EmissoesCO2",
    "AreaFlorestadaPercentual",
    "MortalidadeInfantil",
    "TaxaImpostoTotal",
    "PrecoGasolina",
    "PopulacaoUrbana",
    "SalarioMinimo",
    "MedicosPorMil",
    "Populacao",
    "PopulacaoForcaTrabalhoPercentual",
    "Densidade",
    "TamanhoForcasArmadas"
)


df_longo <- df %>%
    select(all_of(colunas_para_plotar)) %>%
    pivot_longer(
        cols = all_of(colunas_para_plotar),
        names_to = "Variavel",            
        values_to = "Valor"               
    )

grafico_densidade <- ggplot(df_longo, aes(x = Valor)) +
    geom_density(fill = "#2a78b5", alpha = 0.7, color = "white") +
    # geom_histogram(bins = 30, fill = "#2a78b5", alpha = 0.7, color = "white") +
    facet_wrap(~ Variavel, scales = "free", ncol = 3) +
    labs(
        title = "Distribuição de Indicadores Globais por País (2023)",
        x = "Valor",
        y = "Densidade"
    ) +
    theme_minimal() +
    theme(
        plot.title = element_text(hjust = 0.5, face = "bold"),
        strip.text = element_text(face = "bold") 
    )

print(grafico_densidade)

Teste de Normalidade

O teste de normalidade é crucial para verificar se os dados numéricos seguem uma distribuição normal, o que é um pré-requisito para muitos testes estatísticos paramétricos (como o Teste t de Student ou ANOVA).

Teste de Shapiro-Wilk

O teste de Shapiro-Wilk fornece as seguintes informações sobre um conjunto de dados:

    1. Os dados seguem uma distribuição normal.
    1. Os dados não seguem uma distribuição normal.

Entende-se conjunto de dados (no caso analisado), cada coluna com um índice sobre os dados de cada país.

Distribuição normal: É a mais importante distribuição de probabilidade, sendo aplicada em inúmeros fenômenos e utilizada para o desenvolvimento teórico de estatística. É também conhecida como distribuição de Gauss, Laplace ou Laplace-Gauss.

Teste Básico de Shapiro-Wilk no R

Para uma análise básica do teste de normalidade, deve-se inserir o vetor de interesse (uma coluna numérica) com os dados a serem analisados, usa-se a função shapiro.test():

test1 <- shapiro.test(df$MortalidadeInfantil)
test1

    Shapiro-Wilk normality test

data:  df$MortalidadeInfantil
W = 0.86165, p-value = 4.174e-12

A interpretação do p-valor:

  • p > 0.05: Os dados podem ser considerados normais. Você pode prosseguir com testes paramétricos (como ANOVA).
  • P < 0.05: Os dados não seguem uma distribuição normal. Você deve considerar transformações ou usar testes não-paramétricos (como Kruskal-Wallis).

Teste de Shapiro-Wilk para o conjunto de dados

# selecionando o mesmo conjunto de dados dos meus plots
colunas_para_testar <- c(
    "TaxaNatalidade",
    "TaxaFertilidade",
    "ExpectativaVida",
    "TaxaDesemprego",
    "TerraAgriculturaPercentual",
    "AreaTerrestreKm2",
    "EmissoesCO2",
    "AreaFlorestadaPercentual",
    "MortalidadeInfantil",
    "TaxaImpostoTotal",
    "PrecoGasolina",
    "PopulacaoUrbana",
    "SalarioMinimo",
    "MedicosPorMil",
    "Populacao",
    "PopulacaoForcaTrabalhoPercentual",
    "Densidade",
    "TamanhoForcasArmadas"
)

# criar dataframe para armazenar os resultados
resultados_normalidade <- data.frame(
    Variavel = character(),
    ShapiroWilk_p_value = numeric(),
    Interpretacao = character(),
    stringsAsFactors = FALSE
)

# realizar o teste de normalidade para todas as colunas selecionadas
for (col in colunas_para_testar) {
    # filtra valores não-ausentes (NA) para o teste
    dados_filtrados <- na.omit(df[[col]])

    if (length(dados_filtrados) < 3) {
        p_value <- NA
        interpretacao <- "Amostra muito pequena (N < 3)"
    } else {
        teste <- shapiro.test(dados_filtrados)
        p_value <- teste$p.value

        if (p_value < 0.05) {
            interpretacao <- "Rejeita H0: Não Normal"
        } else {
            interpretacao <- "Não Rejeita H0: Distribuição Normal"
        }
    }

    # adicionar o resultado ao dataframe
    resultados_normalidade[nrow(resultados_normalidade) + 1, ] <- c(col, p_value, interpretacao)
}

# plotar via pacote gt
library(gt)
gt(resultados_normalidade)
Variavel ShapiroWilk_p_value Interpretacao
TaxaNatalidade 2.69875917384226e-08 Rejeita H0: Não Normal
TaxaFertilidade 1.12087320173536e-10 Rejeita H0: Não Normal
ExpectativaVida 8.02908862338933e-05 Rejeita H0: Não Normal
TaxaDesemprego 1.57916563935281e-10 Rejeita H0: Não Normal
TerraAgriculturaPercentual 0.000598713593217884 Rejeita H0: Não Normal
AreaTerrestreKm2 9.54101633213065e-26 Rejeita H0: Não Normal
EmissoesCO2 7.39820077387315e-28 Rejeita H0: Não Normal
AreaFlorestadaPercentual 3.42786649089169e-06 Rejeita H0: Não Normal
MortalidadeInfantil 4.17419654709054e-12 Rejeita H0: Não Normal
TaxaImpostoTotal 2.42986434096834e-16 Rejeita H0: Não Normal
PrecoGasolina 0.965803570725806 Não Rejeita H0: Distribuição Normal
PopulacaoUrbana 7.16551678317921e-27 Rejeita H0: Não Normal
SalarioMinimo 9.15869372810545e-17 Rejeita H0: Não Normal
MedicosPorMil 3.42455848258256e-10 Rejeita H0: Não Normal
Populacao 1.18691069208869e-27 Rejeita H0: Não Normal
PopulacaoForcaTrabalhoPercentual 0.300194782119932 Não Rejeita H0: Distribuição Normal
Densidade 3.81361558772807e-29 Rejeita H0: Não Normal
TamanhoForcasArmadas 3.04552884606606e-23 Rejeita H0: Não Normal

A maioria das nossas variáveis não segue a distribuição normal. Isso condiz com a natureza dos nossos dados, pois não se trata de dados gerados ao acaso, mas sim dados do mundo real influenciados por políticas internacionais e normas públicas, que podem adicionar todo tipo de viés aos dados absolutos.

Exemplo de distribuição que não segue a normalidade:

ggplot(df, aes(x = MortalidadeInfantil))+
    geom_density(fill = "#b5692a", alpha = 0.7, color = "white") +
    theme_minimal()

As variáveis PrecoGasolina e PopulacaoForcaTrabalhoPercentual são as únicas que apresentaram uma distribuição normal no nosso dataset.

Exemplo de distribuição normal:

ggplot(df, aes(x = PrecoGasolina))+
    geom_density(fill = "#2fca49", alpha = 0.7, color = "white") +
    theme_minimal()

Correlação das Variáveis

Observa-se que algumas variáveis pertencem à mesma categoria de medida. Pode-se selecionar variáveis com medidas sócio-econômicas e observar se há correlação entre elas no nosso dataset.

Variáveis Sócio-Econômicas

colunas_para_correlacionar <- c(
    "TaxaNatalidade",
    "TaxaFertilidade",
    "ExpectativaVida",
    "TaxaDesemprego",
    "MortalidadeInfantil",
    "TaxaImpostoTotal",
    "SalarioMinimo",
    "Densidade"
)

# importar pacote
library(GGally)
 
# correlatograma
ggpairs(df, columns = colunas_para_correlacionar, ggplot2::aes(fill="#3d85bc", alpha=0.6)) 

Variáveis Ambientais

colunas_para_correlacionar_amb <- c(
    "TerraAgriculturaPercentual",
    "AreaTerrestreKm2",
    "EmissoesCO2",
    "AreaFlorestadaPercentual",
    "PopulacaoUrbana"
)

# importar pacote
library(GGally)
 
# correlatograma
ggpairs(df, columns = colunas_para_correlacionar_amb, ggplot2::aes(fill="#3d85bc", alpha=0.6)) 

Testes Estatísticos

Testes estatísticos funcionam baseados na observação de várias amostras pertencentes à um grupo maior. As diferenças nas médias nos diferentes grupos que mostram a significância estatística de um teste. No caso do dataset utilizado, somente temos as amostras, sem nenhum grupo maior para fazer um teste.

A fim de contornar esse problema, é necessário formar grupos com as amostras. Para isso é necessário importar os dados de países e continentes - a comparação de grandes grupos (continentes) vai permitir a aplicabilidade dos testes.

# importar dataset
continents <- read.csv("https://gist.githubusercontent.com/stevewithington/20a69c0b6d2ff846ea5d35e5fc47f26c/raw/13716ceb2f22b5643ce5e7039643c86a0e0c6da6/country-and-continent-codes-list-csv.csv")

colnames(continents)
[1] "Continent_Name"            "Continent_Code"           
[3] "Country_Name"              "Two_Letter_Country_Code"  
[5] "Three_Letter_Country_Code" "Country_Number"           

Vamos usar a variável Two_Letter_Country_Code para realizar um JOIN entre as duas tabelas.

# importar pacote
library(dplyr)

# vamos unir os itens do continents (direita) para os itens do df (esquerda) - por isso um LEFT JOIN
df2 <- left_join(df,continents, by=c("Abreviacao"="Two_Letter_Country_Code"))

colnames(df2)
 [1] "Pais"                             "Densidade"                       
 [3] "Abreviacao"                       "TerraAgriculturaPercentual"      
 [5] "AreaTerrestreKm2"                 "TamanhoForcasArmadas"            
 [7] "TaxaNatalidade"                   "CodigoDiscagem"                  
 [9] "CapitalCidadePrincipal"           "EmissoesCO2"                     
[11] "IPC"                              "MudancaIPCPercentual"            
[13] "CodigoMoeda"                      "TaxaFertilidade"                 
[15] "AreaFlorestadaPercentual"         "PrecoGasolina"                   
[17] "PIB"                              "MatriculaPrimariaBrutaPercentual"
[19] "MatriculaSuperiorBrutaPercentual" "MortalidadeInfantil"             
[21] "MaiorCidade"                      "ExpectativaVida"                 
[23] "TaxaMortalidadeMaterna"           "SalarioMinimo"                   
[25] "LinguaOficial"                    "GastoSaudeProprioBolso"          
[27] "MedicosPorMil"                    "Populacao"                       
[29] "PopulacaoForcaTrabalhoPercentual" "ReceitaFiscalPercentual"         
[31] "TaxaImpostoTotal"                 "TaxaDesemprego"                  
[33] "PopulacaoUrbana"                  "Latitude"                        
[35] "Longitude"                        "Continent_Name"                  
[37] "Continent_Code"                   "Country_Name"                    
[39] "Three_Letter_Country_Code"        "Country_Number"                  

Agora temos ambos os conjuntos no mesmo dataset df2.

Plot com ggplot

A partir desses dados vamos fazer uma análise comparativa entre os continentes.

Transposição do Dataset

library(dplyr)
library(ggplot2)
library(tidyr)

# Usando o pacote "dplyr" para filtrar os NAs da coluna Continent_Name
df_limpo <- df2 %>%
    filter(!is.na(Continent_Name)) %>% # o "!" significa uma negativa   
    filter(Densidade <= 5000) # Para remover micro estados com pop. grandes


#===============================================================================
# Extender o dataset para que todas as variáveis possam ser acessadas

# Colunas não numéricas
colunas_id <- c(
    "Pais",
    "Abreviacao",
    "CodigoDiscagem",
    "CapitalCidadePrincipal",
    "MaiorCidade",
    "LinguaOficial",
    "CodigoMoeda",               
    "Continent_Name",
    "Continent_Code",
    "Country_Name",
    "Three_Letter_Country_Code",
    "Country_Number",
    "Latitude",                 
    "Longitude"                  
)

colunas_indicadores_numericos <- df_limpo %>%
    # Seleciona todas as colunas que NÃO estão na lista de IDs
    select(-all_of(colunas_id)) %>%
    # E então seleciona daquelas, apenas as que são NUMÉRICAS (double/integer)
    select(where(is.numeric)) %>%
    colnames()

df_limpo$IPC <- as.numeric(df_limpo$IPC)

# função pivot_longer() -> extender o dataset na vertical 
df_longo_indicadores <- df_limpo %>%
    pivot_longer(
        cols = all_of(colunas_indicadores_numericos),
        names_to = "Indicador",
        values_to = "Valor",        
        values_drop_na = FALSE
    )

Agora tempos o dataframe df_longo_indicadores, que é uma transposição do dataset orignial (manteve algumas colunas, mas outras foram transpostas em linhas). Segue a nova estrutura dele:

gt(head(df_longo_indicadores))
Pais Abreviacao CodigoDiscagem CapitalCidadePrincipal IPC CodigoMoeda MaiorCidade LinguaOficial Latitude Longitude Continent_Name Continent_Code Country_Name Three_Letter_Country_Code Country_Number Indicador Valor
Afghanistan AF 93 Kabul 149.9 AFN Kabul Pashto 33.93911 67.70995 Asia AS Afghanistan, Islamic Republic of AFG 4 Densidade 60.00
Afghanistan AF 93 Kabul 149.9 AFN Kabul Pashto 33.93911 67.70995 Asia AS Afghanistan, Islamic Republic of AFG 4 TerraAgriculturaPercentual 58.10
Afghanistan AF 93 Kabul 149.9 AFN Kabul Pashto 33.93911 67.70995 Asia AS Afghanistan, Islamic Republic of AFG 4 AreaTerrestreKm2 652230.00
Afghanistan AF 93 Kabul 149.9 AFN Kabul Pashto 33.93911 67.70995 Asia AS Afghanistan, Islamic Republic of AFG 4 TamanhoForcasArmadas 323000.00
Afghanistan AF 93 Kabul 149.9 AFN Kabul Pashto 33.93911 67.70995 Asia AS Afghanistan, Islamic Republic of AFG 4 TaxaNatalidade 32.49
Afghanistan AF 93 Kabul 149.9 AFN Kabul Pashto 33.93911 67.70995 Asia AS Afghanistan, Islamic Republic of AFG 4 EmissoesCO2 8672.00

Agora é possível selecionar um subset de características e analisar de forma junta em múltiplos boxplots, que vão apresentar as tendências dos continentes.

Criação dos Plots

Variáveis Sócio-Econômicas

soc_eco <- c(
    "TaxaNatalidade",
    "TaxaFertilidade",
    "ExpectativaVida",
    "TaxaDesemprego",
    "MortalidadeInfantil",
    "TaxaImpostoTotal",
    "SalarioMinimo",
    "Densidade"
)

df_longo_indicadores %>%
    filter(Indicador %in% soc_eco) %>%
    ggplot(aes(x = Continent_Name, y = Valor, color = Indicador, fill=Indicador)) +
    geom_boxplot(alpha=0.6) +
    geom_jitter( alpha=0.6) +
    facet_wrap(~ Indicador, scales = "free", ncol = 2) +
    theme_minimal() +
    theme(
        axis.text.x = element_text(angle=45,hjust=1,vjust=1),
        legend.position = "top"
    )

Variáveis Ambientais

amb <- c(
    "TerraAgriculturaPercentual",
    "AreaTerrestreKm2",
    "EmissoesCO2",
    "AreaFlorestadaPercentual",
    "PopulacaoUrbana"
)

df_longo_indicadores %>%
    filter(Indicador %in% amb) %>%
    ggplot(aes(x = Continent_Name, y = Valor, color = Indicador, fill=Indicador)) +
    geom_boxplot(alpha=0.6) +
    geom_jitter( alpha=0.6) +
    facet_wrap(~ Indicador, scales = "free", ncol = 2) +
    theme_minimal() +
    theme(
        axis.text.x = element_text(angle=45,hjust=1,vjust=1),
        legend.position = "top"
    )

Testes estatísticos - Parte II

Anteriormente foi realizado o teste de Shapiro-Wilk, que informa se a distribuição de uma variável (ou dos resíduos de um modelo) desvia significativamente da distribuição normal. Ou seja, se na distribuição de um dos índices por país (População urbana, por exemplo) está seguindo uma distribuição normal em todos os países listados.

O teste de Shapiro-Wilk é também classificado como um teste de suposição (pré-teste/diagnóstico). Ele vai indicar a normalidade dos dados para realização de um teste primário (teste de hipótese), como uma Análise de Variâncias (ANOVA).

Como visto anteriormente, a princípio a ANOVA só pode ser realizada com dados paramétricos (dados com distribuição normal).